-- WakuseiM
-- created by cheny3
-- 变异体冈布奥模块

module("WakuseiM", package.seeall);

local wakuseiTable = {};
local wakuseiPetTable = {};

-- 载入配置表
local _init = false;
local loadCsv = function()
    if _init then return end
    _init = true;

    wakuseiTable = {};
    wakuseiPetTable = {};

    local wakusei_table_CSV = get_wakusei_CSV();
    for i = 1, #wakusei_table_CSV do
        local row = wakusei_table_CSV[i];

        wakuseiTable[row.id] = row;
        wakuseiPetTable[row.pet_id] = row;
    end
end

-- 模块初始化操作
function init()
    loadCsv();

    EventMgr.removeAll("WakuseiM");

    -- 进入下一层
    EventMgr.register("WakuseiM", event.NEXT_FLOOR, whenEnterNext);

    -- 关注离开地牢事件
    EventMgr.register("WakuseiM", event.LEAVE_DUNGEON, whenEnterNext);

    -- 关注回层事件
    EventMgr.register("WakuseiM", event.BACK_FLOOR, whenEnterNext);
end

-- 进入下一层触发
function whenEnterNext()
    local props = PropM.fetchProps(ME.user, "wakusei_clear");
    for _, prop in ipairs(props) do
        PropM.trigger(ME.user, prop[1], prop[2]);
    end
end

-- 查询
function query(id, path)
    local m = wakuseiTable[id];

    if not m or not path then
        return m;
    end

    return m[path];
end

-- 抽取出现的冈布奥
function fetchWakusei()
    local id, petId;

    -- 出战和链接宠物
    local lictors = ME.user.dbase:query("lictor_pets", {});
    local activePet = ME.user.dbase:query("active_pet");

    local fetchIds = {};
    for _, id in pairs(table.keys(wakuseiTable)) do
        repeat
            petId = query(id, "pet_id");
            if activePet == petId or table.indexOf(lictors, petId) >= 0 then
                -- 出战和链接的不能出现
                break;
            end

            table.insert(fetchIds, id);
        until true
    end

    table.sort(fetchIds);

    -- 抽一个
    local rand = DungeonM.getRandSeed("wakusei_fetch");
    local index = rand % #fetchIds + 1;   -- 客户端下标多1
    local id = fetchIds[index];

    return { ["wakusei_id"] = id };
end

-- 给玩家附上技能
function exchangeWakuseiSkill(pos)
     local grid = DungeonM.getGridByPos(pos);

    -- 如果不是变异体
    if grid.type ~= GRID_TYPE_WAKUSEI or
        grid.state == GRID_STATE_DISABLE then
        trace("WakuseiM", "不是变异体或已失效。");
        return false;
    end

    -- 获得能力的变异体信息
    local id = grid.wakusei_id;
    local wakuseiInfo = query(id);

    local skillId = wakuseiInfo["slime_skill"];
    local attrib = wakuseiInfo["recover_attrib"];
    local valueLimit = wakuseiInfo["recover_limit"];

    -- 专属技阶位（根据冈布奥1号的等级）
    local petId = query(id, "skill_level_pet");
    local pet = PetM.getMyPet(petId);

    -- 如果不是出战或者链接的，肯定有问题，直接返回
    if not PetM.isActivePet(petId) and
        not PetM.isLictorPet(petId) then
        return false;
    end

    local specialSkill = PetM.query(petId, "special");
    specialSkill = FormulaM.invoke("CALC_FINAL_SKILL", pet, specialSkill);
    local level = SkillM.query(specialSkill, "level");

    -- 记录属性
    local propId = PropM.getPropId("gain_slime_skill")
    local prop = { propId, tostring(skillId), level, -1};
    PropM.record(ME.user, prop, "wakusei");

    -- 给玩家补全能力
    local curValue = DungeonServiceM.queryDungeonAttrib(attrib);
    local value = valueLimit - curValue;

    if value >= 0 then
        DungeonServiceM.addDungeonAttrib(attrib, value);
    end

    -- 尝试给玩家奖励
    local bonus = tryDoBonus(id);

    -- 格子设为失效
    grid:changeState(GRID_STATE_DISABLE);

    EventMgr.fire(event.WAKUSEI_EXCHANGE, {["pos"] = grid:getPos(), ["bonus"] = bonus});

    return true;
end

-- 尝试给玩家奖励
function tryDoBonus(id)
    local configBonus = query(id, "bonus");
    local prefix = "formula_";
    if type(configBonus) == "string" and string.startWith(configBonus, prefix) then
        -- 配置了公式，先自行计算一遍
        local formulaName = string.sub(configBonus, string.len(prefix) + 1);
        configBonus = FormulaM.invoke(formulaName, ME.user);
    end

    if type(configBonus) == "table" then
        -- 奖励
        for _, bonus in pairs(configBonus) do
            BonusM.doBonus(bonus, "wakusei");
        end
    else
        configBonus = {};
    end

    return configBonus;
end

-- 变异体冈布奥通过能力复制获得的专属技
function wakuseiSpecialSkill()
    -- 出战和链接宠物
    local lictors = ME.user.dbase:query("lictor_pets", {});
    local activePet = ME.user.dbase:query("active_pet");

    local special = {};
    for id, info in pairs(wakuseiTable) do
        repeat
            -- 变异体冈布奥专属
            local petId = info["pet_id"];
            local skillId = PetM.query(petId, "special");

            if activePet == petId or table.indexOf(lictors, petId) >= 0 then
                -- 链接/出战的，肯定不是复制得到的
                break;
            end

            -- 基础技能
            local baseSkill = SkillM.findBaseSkill(skillId);
            table.insert(special, baseSkill);
        until true;
    end

    return special;
end

-- 根据宠物ID排序信息
function queryByPetId(petId, path)
    local m = wakuseiPetTable[petId];

    if not m or not path then
        return m;
    end

    return m[path];
end